#include "DistribViewer.h"
#include "../ro/visual/histogram/histogram.h"

BEGIN_EVENT_TABLE(DistribViewer, wxScrolledWindow)
	EVT_MOUSE_EVENTS(DistribViewer::OnMouseEvent)
	//EVT_PAINT(DistribViewer::OnPaint)
END_EVENT_TABLE()

DistribViewer::DistribViewer(wxWindow* parent, wxWindowID id):
wxScrolledWindow(parent, id, wxDefaultPosition, wxSize(512, 256), wxFULL_REPAINT_ON_RESIZE)
{
	m_mode = -10;
	m_quantity = 0;
	m_type = -10;

	m_pens[0] = wxColor("BLUE");
	m_pens[1] = wxColor("CORAL");
	m_pens[2] = wxColor("GREEN");
	m_pens[3] = wxColor("ORANGE");
	m_pens[4] = wxColor("MEDIUM TURQUOISE");
	
	m_brushs[0] = wxColor("MEDIUM VIOLET RED");
	m_brushs[1] = wxColor("WHEAT");
	m_brushs[2] = wxColor("YELLOW");
	m_brushs[3] = wxColor("PALE GREEN");
	m_brushs[4] = wxColor("PINK");

	//SetDoubleBuffered(true);
}
void DistribViewer::OnMouseEvent(wxMouseEvent& event)
{
	if(event.ButtonDown())
	{
		wxPaintDC dc(this);
		DoPrepareDC(dc);
		wxColor pix;
		dc.DrawText("point", event.GetX(), event.GetY());
		if(dc.GetPixel(event.GetX(), event.GetY(), &pix))
			wxMessageBox(wxString::Format("coords(%d, %d); color(%X, %X, %X);",event.GetX(), event.GetY(), pix.Red(), pix.Green(), pix.Blue()));
	}
}
//void DistribViewer::OnPaint(wxPaintEvent& WXUNUSED(event))
void DistribViewer::OnDraw(wxDC& dc)
{
	//wxPaintDC dc(this);
	//DoPrepareDC(dc);

	int width = GetSize().GetWidth();
	int height = GetSize().GetHeight();
	int i, j, x, x0, x1;
	//hist vars
	float outy = 35.0f;
	float outyd = 15.0f;
	float outx = 5.0f;
	float dw = ((float)width - 2 * outx) / 256.0f;
	float dh = (float)height - outy - 10.0f - outyd;
	roPreImage* img;
	float* Hv;

	
	//init background
	dc.SetBackgroundMode(wxSOLID);
	//white background
	dc.SetBrush(wxBrush(wxColor(255, 255, 255)));
	dc.SetPen(wxPen(wxColor(160, 160, 160), 1));
	dc.DrawRectangle(outx, outy, width - 2 * outx, height - outy - outyd);
	//end of backgrownd drawning
	
	if(!m_quantity || m_type == -10)
	{
		dc.DrawText("Data not founded.", width / 2, height / 2);
		return;
	}
	

	using namespace roto::histogram;

	switch(m_mode)
	{
	case DistribInit::MODE_HISTOGRAM:

		if(m_type > -1 && m_type < 3)
		{
			for(i = 0; i < m_quantity; ++ i)
			{
				dc.SetBrush(wxBrush(m_pack[i]->brush(), wxSOLID));
				dc.SetPen(wxPen(m_pack[i]->pen(), 2, wxSOLID));
				
				dc.DrawRectangle(5, 5 + 15 * i, 50, 10);
				dc.DrawText(m_pack[i]->comment(), 5 + 50 + 5, 5 + 15 * i - 2);

				dc.SetPen(wxPen(m_pack[i]->pen(), 1, wxSOLID));

				if(m_pack[i]->visible())
				{
					img = m_pack[i]->source();
					Hv = calc_norm_histogram_array(
						get_histogram_array(
						img->chanel(m_type), img->width(), img->height()));

					for(x = 0; x < 256; ++ x)
					{
						x0 = (int)((float)x * dw + outx);
						x1 = (int)((float)(x + 1) * dw + outx);
						dc.DrawRectangle(x0, (dh - Hv[x] * dh + outy), x1 - x0, (Hv[x] * dh));
					}
				}
			}
		}
		else if(m_type < 0)
		{
			wxString comment;
			unsigned long color;
			i = m_quantity - 1;
			for(j = 0; j < 3; ++ j)
			{
				switch(j)
				{
				case 0:
					if(m_type == -1) comment = "Red", color = 0xff0000;
					else if(m_type == -2) comment = "Hue", color = 0xF5C536;
					else if(m_type == -3) comment = "Hue", color = 0xF5C536;
					break;
				case 1:
					if(m_type == -1) comment = "Green", color = 0x00ff00;
					else if(m_type == -2) comment = "Saturation", color = 0x92C7FC;
					else if(m_type == -3) comment = "Saturation", color = 0x92C7FC;
					break;
				case 2:
					if(m_type == -1) comment = "Blue", color = 0x0000ff;
					else if(m_type == -2) comment = "Lightness(Intensity)", color = 0xFA61F7;
					else if(m_type == -3) comment = "Brightness(Value)", color = 0xFA61F7;
					break;
				}
				//m_pack[i]->color(wxColor(color), wxColor(color));
				dc.SetBrush(wxBrush(color, wxSOLID));
				dc.SetPen(wxPen(color, 2, wxSOLID));
				
				dc.DrawRectangle(5, 5 + 15 * j, 50, 10);
				dc.DrawText(comment, 5 + 50 + 5, 5 + 15 * j - 2);

				dc.SetPen(wxPen(color, 1, wxSOLID));

				if(m_pack[i]->visible())
				{
					img = m_pack[i]->source();
					Hv = calc_norm_histogram_array(
						get_histogram_array(
						img->chanel(j), img->width(), img->height()));

					for(x = 0; x < 256; ++ x)
					{
						x0 = (int)((float)x * dw + outx);
						x1 = (int)((float)(x + 1) * dw + outx);
						dc.DrawRectangle(x0, (dh - Hv[x] * dh + outy), x1 - x0, (Hv[x] * dh));
					}
				}
			}
		}

		for(x = 0; x < 256; ++ x)
		{
			x0 = (int)((float)x * dw + outx);
			x1 = (int)((float)(x + 1) * dw + outx);
			dc.SetBrush(wxBrush(wxColor(x, x, x)));
			dc.SetPen(wxPen(wxColor(x, x, x), 1));
			dc.DrawRectangle((int)((float)x * dw + outx), (dh + outy), x1 - x0, 9);
		}
		dc.DrawText("0", outx, (dh + outy)+11);
		dc.DrawText("255", (float)width - 2.0f * outx - 14, (dh + outy)+11);
		break;
	}

}
void DistribViewer::Display(int mode = 1, int type = 2)
{
	m_mode = mode;
	m_type = type;
	Refresh();
}
void DistribViewer::SetMode(int mode)
{
	m_mode = mode;
	Refresh();
}
void DistribViewer::SetType(int type)
{
	m_type = type;
	Refresh();
}
int DistribViewer::AddImage(roPreImage* img, const wxString &comment,
		unsigned long pen, unsigned long brush)
{
	wxColor c_pen = (pen == 0? m_pens[m_quantity] : pen);
	wxColor c_brush = (brush == 0? m_brushs[m_quantity] : brush);

	m_pack[m_quantity] = new DistribProperty(img, m_quantity, comment, c_pen, c_brush);
	m_quantity ++;
	return m_quantity - 1;
}

